from django.shortcuts import render, redirect, get_object_or_404, HttpResponse
from django.contrib.auth import login, logout, authenticate
from .forms import LoginForm, ChangePassword, UserGroupForm
from .models import LoginRecord, UserInfo, UserGroup
from django.contrib.auth.decorators import login_required
from django.http import Http404
from .forms import UserForm
from django.db.models import Q
import json
import datetime
import pymongo
import requests
import re
from django.contrib.auth.decorators import permission_required

myclient = pymongo.MongoClient("mongodb://localhost:27017/")
mydb = myclient["test3"]
mycoldl = mydb["dlhistory"]  # 下载的历史记录


def UserIP(request):
    '''获取用户IP'''
    ip = ''
    if 'HTTP_X_FORWARDED_FOR' in request.META:
        ip = request.META['HTTP_X_FORWARDED_FOR']
    else:
        ip = request.META['REMOTE_ADDR']
    return ip

# 根据ip地址查询出IP所在的地理位置


def get_position(ip):

    str_pos = u''
    url = "https://www.ip138.com/iplookup.asp?ip={}&action=2".format(ip)
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.100 Safari/537.36'
    }

    # 获取响应
    response = requests.get(url=url, headers=headers)
    response.encoding = "gb2312"
    html = response.text

    match = re.finditer('"(prov|city|ct)":"(.*?)"', html)
    for m in match:
        str_pos += m.group().split("\"")[-2] + " "

    return str_pos


def user_login(request):
    if request.method == 'POST':  # post方法处理
        form = LoginForm(request.POST)
        if form.is_valid():  # 使用表单类自带的is_valid()方法一步完成数据验证工作
            # authenricate作用:认证给出的用户名和密码，使用 authenticate() 函数。它接受两个参数，用户名 username 和 密码 password ，
            # 并在密码对给出的用户名合法的情况下返回一个 User 对象。 如果密码不合法，authenticate()返回None。
            user = authenticate(request, username=request.POST.get(
                'username'), password=request.POST.get('password'))
            if user:
                login(request, user)  # authenricate只是认证，login函数使用户真正登录
                LoginRecord.objects.create(type=u'用户登录', user=request.user, action=u'用户登录', ip=UserIP(
                    request), position=get_position(UserIP(request)), content='用户登录 %s' % request.user)
                request.session['username'] = request.POST.get(
                    'username')  # 在session中保留用户名
                request.session['password'] = request.POST.get(
                    'password')  # 在seesion中保留密码
                return redirect("/index")  # 登陆成功，返回到index页面
        LoginRecord.objects.create(type=u'用户登录', user=request.POST.get('username'), action=u'用户登录', ip=UserIP(
            request), position=get_position(UserIP(request)), content=u'用户登录失败 %s' % request.POST.get('username'))
        return render(request, 'base/login.html', {'form': form})
    else:  # 对于非POST方法发送数据时，比如GET方法请求页面，返回空的表单，让用户可以填入数据；
        if "username" in request.session and "password" in request.session:
            user = authenticate(
                request, username=request.session['username'], password=request.session['password'])
            login(request, user)  # authenricate只是认证，login函数使用户真正登录
            LoginRecord.objects.create(type=u'用户登录', user=request.user, action=u'用户登录', ip=UserIP(
                request), position=get_position(UserIP(request)), content='用户登录 %s' % request.user)
            return redirect("/index")  # 登陆成功，返回到index页面
        else:
            form = LoginForm()
            return render(request, 'base/login.html', {'form': form})


def user_logout(request):
    # 删除 session
    del request.session['username']
    del request.session['password']
    logout(request)
    return redirect("/")


@login_required
def change_password(request):
    user = get_object_or_404(UserInfo, username=request.user)
    if request.method == 'POST':
        form = ChangePassword(request.POST, instance=user)
        if form.is_valid():
            form.save()
            return redirect('/')
    else:
        form = ChangePassword(instance=user)
    return render(request, "user/changepasswd.html", {"form": form})


@login_required
def index(request):

    if not request.user.has_perm("wenjuan.view_HunanNzz") and not request.user.has_perm("wenjuan.view_OverallAdmin"):
        return render(request, 'base/index.html')

    elif request.user.has_perm("wenjuan.view_OverallAdmin"):
        return render(request, 'base/index_overall.html')

    elif request.user.has_perm("wenjuan.view_HunanNzz"):
        return render(request, 'base/index_hunan.html')


@login_required
@permission_required(perm='userauth.view_user')
def user_list(request):
    return render(request, 'user/user_list.html')


@login_required
@permission_required(perm='userauth.view_user')
def user_listSolve(request):
    """
        如果是get请求则只展示用户数据 
    """
    if request.method == 'GET':
        # 获取页数、每页的数据量以及查询内容
        pageNumber = request.GET.get('pageNumber')
        pageSize = request.GET.get('pageSize')
        searchText = request.GET.get('searchText', None)
        # 根据数据，计算分页后的UserInfo对象切片
        # 例如pageNumber = 2,pageSize = 10，则需要服务器返回[10:20]的数据片段，切片左闭右开
        if searchText:
            # 搜索筛选后，再计算分页
            users = UserInfo.objects.filter(Q(username__contains=searchText) | Q(
                name__contains=searchText) | Q(address__contains=searchText) | Q(
                phone__contains=searchText))[int(pageSize)*(int(pageNumber)-1):int(pageSize)*int(pageNumber)]
            # 计算总条数
            total = UserInfo.objects.filter(Q(username__contains=searchText) | Q(
                name__contains=searchText) | Q(address__contains=searchText) | Q(
                phone__contains=searchText)).count()
        else:
            # 直接计算分页
            users = UserInfo.objects.all()[int(
                pageSize)*(int(pageNumber)-1):int(pageSize)*int(pageNumber)]
            # 获取总数据量
            total = UserInfo.objects.count()
        # 记录每行的具体数据
        rows = []
        # 定义返回值data的格式
        data = {
            'total': total,
            'rows': rows
        }
        # 遍历users对象，将数据放入rows种
        for user in users:
            rows.append({
                'id': user.id,
                'username': user.username,
                'name': user.name,
                'address': user.address,
                'phone': user.phone,
                'qq': user.qq,
                'is_active': user.is_active
            })
        return HttpResponse(json.dumps(data), content_type='application/json')


@login_required
@permission_required(perm='userauth.view_loginrecord')
def user_audit(request):
    '''
    审计日志
    '''
    if request.user.is_superuser:
        return render(request, 'user/user_audit.html')
    else:
        raise Http404

def user_auditSolve(request):
    if request.method == 'GET':
        pageNumber = request.GET.get('pageNumber')
        pageSize = request.GET.get('pageSize')
        searchText = request.GET.get('searchText', None)
        if searchText:
            records = LoginRecord.objects.filter(Q(user__contains=searchText) | Q(
                date__contains=searchText) | Q(type__contains=searchText) | Q(
                ip__contains=searchText) | Q(position__contains=searchText) | Q(
                content__contains=searchText))[int(pageSize)*(int(pageNumber)-1):int(pageSize)*int(pageNumber)]
            total = LoginRecord.objects.filter(Q(user__contains=searchText) | Q(
                date__contains=searchText) | Q(type__contains=searchText) | Q(
                ip__contains=searchText) | Q(position__contains=searchText) | Q(
                content__contains=searchText)).count()
        else:
            records = LoginRecord.objects.all()[int(pageSize)*(int(pageNumber)-1):int(pageSize)*int(pageNumber)]
            total = LoginRecord.objects.count()
        rows = []
        data = {
            'total': total,
            'rows': rows
        }
        for record in records:
            rows.append({
                'username': record.user,
                'time': record.date,
                'type': record.type,
                'ip': record.ip,
                'address': record.position,
                'content': record.content
            })
    return HttpResponse(json.dumps(data,cls=DateEncoder), content_type='application/json')

#处理dict字典无法处理事件类型的问题
class DateEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj,datetime.datetime):
            return obj.strftime("%Y-%m-%d %H:%M:%S")
        else:
            return json.JSONEncoder.default(self,obj)

@login_required
def user_add(request):
    if request.method == 'GET':
        form = UserForm()
        return render(request, 'user/user_add.html', {'form': form})
    else:
        form = UserForm(request.POST)
        if form.is_valid():
            '''合法之后修改密码和组'''
            username = request.POST.get('username')
            password1 = request.POST.get('password1')
            password2 = request.POST.get('password2')
            group_select = request.POST.getlist('group_sel')
            group_delete = request.POST.getlist('group_del')
            perm_select = request.POST.getlist('perm_sel')
            perm_delete = request.POST.getlist('perm_del')
            if password1 and password1 == password2:
                form.save()  # 更新数据，相当于MYSQL中的Insert
                user = get_object_or_404(UserInfo, username=username)
                print(user)
                user.set_password(password1)
                user.save()
                # 添加用户至UserGroup
                user.groups.add(*group_select)
                user.groups.remove(*group_delete)
                # 授予用户权限
                user.user_permissions.add(*perm_select)
                user.user_permissions.remove(*perm_delete)
                # UserInfo.objects.create(**obj.cleaned_data)
                return redirect("/user_list/")
        else:
            return render(request, "user/user_add.html")


@login_required
def user_edit(request, aid):
    # 前端请求数据，获得目标用户，返回到指定页面
    if request.method == 'GET':
        user_obj = UserInfo.objects.filter(id=aid).first()
        form = UserForm(instance=user_obj)
        return render(request, 'user/user_edit.html', {'form': form, 'aid': aid})
    # 修改后进行提交
    elif request.method == "POST":
        user_obj = UserInfo.objects.filter(id=aid).first()
        form = UserForm(request.POST, instance=user_obj)
        if form.is_valid():
            group_select = request.POST.getlist('group_sel')
            group_delete = request.POST.getlist('group_del')
            perm_select = request.POST.getlist('perm_sel')
            perm_delete = request.POST.getlist('perm_del')
            form.save()
            # 修改用户的组，用户的权限
            user_obj.groups.add(*group_select)
            user_obj.groups.remove(*group_delete)
            user_obj.user_permissions.add(*perm_select)
            user_obj.user_permissions.remove(*perm_delete)

        return redirect("/user_list")


def user_del(request):
    # 删除成功的状态提示
    ret = {'status': True}
    try:
        # 获取前端发送过来的ID号
        userId = request.POST.getlist('userId[]')
        UserInfo.objects.filter(id__in=userId).delete()
    # 删除失败的状态提示
    except Exception as e:
        ret['status'] = False
    return HttpResponse(json.dumps(ret))


@login_required
def user_group_list(request):
    '''用户组信息'''
    groups = UserGroup.objects.all()
    return render(request, 'user/user_group_list.html', {'groups': groups})


@login_required
@permission_required(perm='userauth.view_usergroup')
def user_group_add(request):
    group = UserGroup()
    if request.method == 'POST':
        form = UserGroupForm(request.POST, instance=group)
        if form.is_valid():
            user_select = request.POST.getlist('user_sel')
            user_delete = request.POST.getlist('user_del')
            perm_select = request.POST.getlist('perm_sel')
            perm_delete = request.POST.getlist('perm_del')
            form.save()
            group.save()
            group.user_set.add(*user_select)
            group.user_set.remove(*user_delete)
            group.permissions.add(*perm_select)
            group.permissions.remove(*perm_delete)
            return redirect("/user_group_list")
    else:
        form = UserGroupForm(instance=group)
    return render(request, 'user/user_group_add.html', {'form': form})


@login_required
def user_group_del(request):

    ret = {'status': True}
    try:
        nid = request.POST.getlist('nid[]')
        print(nid)
        obj = UserGroup.objects.filter(id__in=nid).delete()
    except Exception as e:
        ret['status'] = False
    return HttpResponse(json.dumps(ret))


@login_required
def user_group_edit(request, aid):
    if request.method == 'GET':
        user_group_obj = UserGroup.objects.filter(id=aid).first()
        form = UserGroupForm(instance=user_group_obj)

        return render(request, 'user/user_group_edit.html', {'form': form, 'aid': aid})

    elif request.method == "POST":
        group_obj = UserGroup.objects.filter(id=aid).first()
        form = UserGroupForm(request.POST, instance=group_obj)
        if form.is_valid():
            user_select = request.POST.getlist('user_sel')
            user_delete = request.POST.getlist('user_del')
            perm_select = request.POST.getlist('perm_sel')
            perm_delete = request.POST.getlist('perm_del')
            form.save()
            # 修改用户的组，用户的权限
            group_obj.user_set.add(*user_select)
            group_obj.user_set.remove(*user_delete)
            group_obj.permissions.add(*perm_select)
            group_obj.permissions.remove(*perm_delete)

        return redirect("/user_group_list")


# 用户下载记录

@login_required
def user_download_history(request):
    user_obj = []
    for x in mycoldl.find():  # 查询所有
        user_obj.append(x)
    return render(request, 'user/download_history.html', {'user_obj': user_obj})


@login_required
def user_permission(request, aid):
    # print(aid)
    user_obj = UserInfo.objects.filter(id=aid).first()
    # print(user_obj)
    user = {}
    permissions = {'wenjuan.view_HenanReview': '审阅河南调查问卷', 'wenjuan.view_HenanWenjuan': '查看河南调查记录',
                   'wenjuan.view_JKwenjuan': '查看健康人群记录', 'wenjuan.view_SFwenjuan': '查看随访调查记录',
                   'suifang.view_suifang': '查看随访名单', 'wenjuan.view_HenanPending': '查看河南未提交名单',
                   'wenjuan.view_HZYYwenjuan': '查看患者调查记录(医院)', 'wenjuan.view_AnhuiWenjuan': '查看安徽调查记录',
                   'wenjuan.view_JKTJwenjuan': '查看健康人群记录(体检)', 'wenjuan.view_HunanPending': '查看湖南未提交名单',
                   'userauth.view_user': '查看用户', 'wenjuan.view_HubeiPending': '查看湖北未提交名单',
                   'wenjuan.view_HubeiWenjuan': '查看湖北调查记录', 'wenjuan.view_wenjuanresult': '查看问卷信息统计',
                   'userauth.view_downloadhistory': '查看下载记录', 'userauth.view_usergroup': '查看用户组',
                   'wenjuan.view_AnhuiPending': '查看安徽未提交名单', 'userauth.view_loginrecord': '查看登录记录',
                   'wenjuan.view_JiangxiReview': '审阅江西调查问卷', 'wenjuan.view_HubeiReview': '审阅湖北调查问卷',
                   'wenjuan.view_HunanWenjuan': '查看湖南调查记录', 'wenjuan.view_JiangxiPending': '查看江西未提交名单',
                   'wenjuan.view_HunanReview': '审阅湖南调查问卷', 'wenjuan.view_HZwenjuan': '查看患者调查记录',
                   'wenjuan.view_JiangxiWenjuan': '查看江西调查记录', 'wenjuan.view_AnhuiReview': '审阅安徽调查问卷',
                   'wenjuan.view_RHwenjuan': '查看入户筛查表记录', 'wenjuan.viewJKHNwenjuan': '查看查看健康人群记录(湖南)',
                   'wenjuan.viewNCXHNwenjuan': '查看脑出血患者记录(湖南)', 'wenjuan.viewNGSwenjuan': '查看脑梗塞患者记录(湖南)'
                   }

    user = {}
    user['username'] = user_obj.username
    arr = []
    if len(user_obj.get_all_permissions()) == 0:
        arr = '该用户没有任何权限'
    else:
        for j in user_obj.get_all_permissions():
            if j in permissions.keys():
                j = permissions[j]
                arr.append(j)
    user['permission'] = arr
    return render(request, 'user/user_permission.html', {'user': user})
